#include "fsm_timer.h"
#include "Bsp.h"

static struct timer_list_t system_timer_node;

void timer_list_init(struct timer_list_t *l)
{
    l->next = l->prev = l;
}

void timer_list_insert(struct timer_list_t *n)
{
    struct timer_list_t *l = &system_timer_node;

    if (l == n)
    {
        return;
    }

    l->prev->next = n;
    n->prev = l->prev;

    l->prev = n;
    n->next = l;
}

void timer_list_remove(struct timer_list_t *n)
{
    if (n == &system_timer_node)
    {
        return;
    }

    n->next->prev = n->prev;
    n->prev->next = n->next;

    n->next = n->prev = n;
}

int timer_list_isempty(const struct timer_list_t *l)
{
    return l->next == l;
}

/*********************************  定时函数  *******************************/
void fsm_timer_init(struct timer_list_t *n, timer_func func, uint16_t nTicks, fsm_timer_ctr flg)
{
    // 断言, 参数不能为空
    BSP_Assert(n);
    BSP_Assert(func);
    
    // 初始化链表
    timer_list_init(n);
    
    // 定时设置
    switch (flg)
    {
    case fsm_timer_one_flg:
        n->nTicks = nTicks;
        n->interval = 0;
        break;
    
    case fsm_timer_period_flg:
        n->nTicks = n->interval = nTicks;
        break;
    
    default:
        break;
    }
    
    // 回调函数
    n->func = func;
}

void fsm_timer_set(struct timer_list_t *n, uint16_t nTicks, fsm_timer_ctr flg)
{
    BSP_Assert(n);
    
    // 关中断
    Bsp_SysTick_Stop();
    
    switch (flg)
    {
    case fsm_timer_one_flg:
        n->nTicks = nTicks;
        n->interval = 0;
        break;
    
    case fsm_timer_period_flg:
        n->nTicks = n->interval = nTicks;
        break;
    
    default:
        break;
    }
    
    // 开中断
    Bsp_SysTick_Start();
}

int fsm_timer_start(struct timer_list_t *n)
{
    int ret = 0;

    BSP_Assert(n);
    
    // 关中断
    Bsp_SysTick_Stop();
    
    if (timer_list_isempty(n) && n->nTicks)
    {
        timer_list_insert(n);
        ret = 1;
    }
    
    // 开中断
    Bsp_SysTick_Start();

    return ret;
}

int fsm_timer_stop(struct timer_list_t *n)
{
    int ret = 1;

    BSP_Assert(n);
    
    n->nTicks = 0;
    
    return ret;
}

int fsm_timer_isActive(struct timer_list_t *n)
{
    if (n == &system_timer_node)
    {
        return 1;
    }
    
    return timer_list_isempty(n);
}

void fsm_system_timer_init(void)
{
    fsm_timer_init(&system_timer_node, fsm_system_timerfunc, system_nTicks_cnt, system_timer_mode);
}

void fsm_timer_handler(void)
{
    struct timer_list_t *p = &system_timer_node;
    
    do
    {
        if (p->nTicks)
        {
            p->nTicks --;
            if(p->nTicks == 0)
            {
                p->nTicks = p->interval;
                (*p->func)();
            }
        }
        else
        {
            // 清理失效定时器
            p = p->prev;
            timer_list_remove(p->next);
        }

        p = p->next;
    } while (p != &system_timer_node);
}
